Loading packages

# JSON libraries
library(rjson)
library(RJSONIO)
library(jsonlite)

# To read the netCDF file (check for better options!)
library(ncdf4)

# To get the min bounding box
library(sp)
library(shotGroups)

# To plot the track of the glider
library(spacetime)
library(trajectories)
library(leaflet)

# To format dates
library(lubridate)

# ?? Not sure why I was using this
library(tidyverse)

# to format text in the console (does not format text in R markdown)
require(crayon)

Writing a function to get the Time dimenson from the glider netCDF file

The following function gets the time dimension from the glider netCDF file and converts it from double to Unix time. The fucnction also extracts the time stamp and the date as well. This function returns a dataframe that has the formatted time in addition the timestamp and the date. This function takes an ncdf4 object as an argument.

formatTimeDim <- function(file){
    tryCatch(
        expr = {
            # Getting the time dimension
            time = file$dim$TIME
            # Formatting time
            time_formatted = as.POSIXct(time$vals, origin="1970-01-01")
            # Extracting the time stamp from the unix time object
            timeStamp = format(time_formatted,'%H:%M:%S')
            # Extracting the date from the unix time object
            date = as.Date(time_formatted)
            # Combining the formatted time, the time stamp and the date in one data frame
            all = cbind.data.frame(time_formatted, timeStamp, date)
            
            message('The time dimension has been successfully formatted!')
          # returning the dataframe
          return(all)
            
        },
        error = function(e){
            message('Caught an error!')
            print(e)
        },
        warning = function(w){
            message('Caught an warning!')
            print(w)
        }
    )    
}

Combining lat and long with time

This function should return a dataframe that has the lat, lon, the time formatted, time stamp and date with no NA data.

combineLatLongWithTime <- function(filePath){
    tryCatch(
        expr = {
              # Reading the file
              file = nc_open(filePath)
              
              # Getting the latitude and longitude
              lon = ncvar_get(file,"LONGITUDE")
              lat = ncvar_get(file,"LATITUDE")
              
              # Calling the time function to get the dataframe that has the time formatted
              time = formatTimeDim(file)
              
              # Combining the time data frame with lat and long. This dataframe has NA values
              dataframe = cbind.data.frame(lat, lon, time)
              
              
              cat(bold("The number of NA this file has is: ", sum(is.na(dataframe))))
              cat("\n")
              
              # removing NA values
              dataframe_No_NA = dataframe %>% drop_na()
              
              return(dataframe_No_NA)
            
            message("dataframe successfully created!")
        },
        error = function(e){
            message('Caught an error!')
            print(e)
        },
        warning = function(w){
            message('Caught an warning!')
            print(w)
        }
    )    
}

A function to plot the track of the netCDF file

This function takes the a datafram that has lat, lon, time_formatted, time stamp and date as an argument. This is the output of the function combineLatLongWithTime I am not sure how to select the first tow colomns of the dataframe that has lat, lon, time…… is it better if I put lat,lon in a seperate dataframe???? It looks to me that lat_lon_time_No_NA %>% select(1:2) makes things more complicated!!!

plotMissionTrack = function(lat_lon_time_No_NA){
  # Setting a projection
  crs = CRS("+proj=longlat +datum=WGS84")
  # Creating an STIDF object
  stidf = STIDF(SpatialPoints(lat_lon_time_No_NA %>% select(1:2),crs), lat_lon_time_No_NA$time_formatted, data.frame(lat_lon_time_No_NA %>% select(1:2)))
  # Creating a track object
  glider_track = Track(stidf)
  # plotting the map
   return(leaflet() %>%addTiles() %>% addPolylines(lat = glider_track@data[,1], lng = glider_track@data[,2]))
}

A function to get the first value of each day in the dataframe

This function also takes a dataframe that has lat, lon, time_fomratted, timestamp and date as an input. This is the output of the function combineLatLongWithTime.

getMissionTrackLabels = function(lat_lon_time_No_NA){
  # Splitting the dataframe based on date
  # This results in a list of dataframes
  list = split(lat_lon_time_No_NA, lat_lon_time_No_NA$date)
  #This provides the first row of each day in the data frame
  first_days = do.call(rbind, (lapply(list, function(x) x[1,])))
  return(first_days)
}

A function to plot the mission track with labels

I’m still thinking of plotting the first value of the mission in green and the last value in red. I think this requiers extracting the first vlaue in a seperate list or a dataframe and the same for the last value and then add them to the plotting function.

plotMissionTrackWithLabels = function(lat_lon_time_No_NA){
  track = plotMissionTrack(lat_lon_time_No_NA)
  first_days = getMissionTrackLabels(lat_lon_time_No_NA)
  return (track %>% addAwesomeMarkers(data = first_days, lat = ~first_days$lat, lng = ~first_days$lon, label = first_days$time_formatted))
}

Providing the path to the netCDF file

# This is where the netCDF data files reside
netCDF_Data_Files_Path = "D:/University/WWU/WWU 5/netCDF sample files/"


netCDF_File2_Name = "sg558_fram_jun2013_R.nc"

Testing plotting the mission track for multiple files

File 1

# This is the files that needs to be read
netCDF_File1_Name = "wallis_mooset01_R.nc"
# This is the complete path to the netCDF file that is being read
file_Path_File1 = paste0(netCDF_Data_Files_Path,netCDF_File1_Name)

lat_lon_time_No_NA_File1 = combineLatLongWithTime(file_Path_File1)
## The time dimension has been successfully formatted!
## The number of NA this file has is:  464
plotMissionTrack(lat_lon_time_No_NA_File1)
x = getMissionTrackLabels(lat_lon_time_No_NA_File1)

plotMissionTrackWithLabels(lat_lon_time_No_NA_File1)

Getting the min bounding box using the library sp

# Converting the dataframe to a SpatialPoints object
lat_lon_spatial_file1 = SpatialPoints(lat_lon_time_No_NA_File1 %>% select(1:2))
# Applying the bbox function
bb_sp = bbox(lat_lon_spatial_file1)

head(lat_lon_spatial_file1)
## SpatialPoints:
##           lat      lon
## [1,] 43.00009 5.993153
## [2,] 43.00021 5.992803
## [3,] 43.00055 5.992498
## [4,] 43.00055 5.992292
## [5,] 43.00059 5.992281
## [6,] 43.00063 5.992271
## Coordinate Reference System (CRS) arguments: NA
bb_sp
##           min      max
## lat 41.674347 43.00926
## lon  5.399076  7.16478

Getting the bbox using the library shotGroups

This function also returns the width and height of the bounding box. Since the projection is WGS84. This information is not useful.

lat_lon = lat_lon_time_No_NA_File1 %>% select(1:2)
names(lat_lon)[1] = "point.x"
names(lat_lon)[2] = "point.y"
bb = getBoundingBox(lat_lon)
bb
## $pts
##     xleft   ybottom    xright      ytop 
## 41.674347  5.399076 43.009263  7.164780 
## 
## $width
## [1] 1.334915
## 
## $height
## [1] 1.765704
## 
## $FoM
## [1] 1.55031
## 
## $diag
## [1] 2.213529

This section is left as a reference in case I lost track of things. This shall be soon deleted after all the functions have been well defined

Getting the first value of each day of the data available in the netCDF file

What I thought of is splitting the dataframe that has all the days in the netCDF file into seperate dataframes each containing the measurement for each day. The first row of each dataframe is then extracted to get the first measurement of that day.

# Splitting the dataframe based on date
# This results in a list of dataframes
#list = split(lat_lon_time_No_NA, lat_lon_time_No_NA$date)
#This provides the first row of each day in the data frame
#first_days = do.call(rbind, (lapply(list, function(x) x[1,])))

# Plotting the glider track with labels
#leaflet() %>%addTiles() %>% addPolylines(lat = glider_track@data[,1], lng = glider_track@data[,2]) %>% addAwesomeMarkers(data = first_days, lat = ~first_days$lat, lng = ~first_days$lon, label = first_days$time_formatted)

Adding the last value of the last day to the labels dataframe

# Getting the last day
#last_day_df = as.data.frame(tail(list, n = 1))
# Setting the name of the columns to the same names of the first_days dataframe
# This makes it easier to combine both dataframes
#names(last_day_df) = colnames(first_days)
#last_day = tail(last_day_df, n=1)
#Adding the last value of the last day to the first_days dataframe
#first_days_plus_last_value = rbind(first_days, last_day)
# Plotting the glider track with labels including the last vlaue of the last day
#leaflet() %>%addTiles() %>% addPolylines(lat = glider_track@data[,1], lng = glider_track@data[,2]) %>% addMarkers(data = first_days_plus_last_value, lat = ~first_days_plus_last_value$lat, lng = ~first_days_plus_last_value$lon, label = first_days_plus_last_value$time_D_formatted)
# This provides a summary of the dataframe based on the date
#lat_lon_time_dateframe %>% group_split(date) %>% map(summary)